﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Text;
using System.Drawing;
using aoprinter.Model;

namespace aoprinter
{
    /// <summary>
    /// printer data set
    /// <para>key: datasourceID</para>
    /// <para>value: dynamic data</para>
    /// </summary>
    public class PrinterData : Dictionary<string, dynamic>
    {
        public void AddCustomDateBind(string bindID, ICustomDataBind dataBinder)
        {
            Add(bindID, dataBinder);
        }

        internal int GetListCount(string bindID)
        {
            if (string.IsNullOrWhiteSpace(bindID))
            {
                return 0;
            }
            if (ContainsKey(bindID) && this[bindID] != null && this[bindID] is IList)
            {
                IList lst = this[bindID] as IList;
                return lst.Count;
            }
            return 0;
        }

        internal string GetListText(string bindID, string memberID = "", int index = 0, bool isCustom = false)
        {
            dynamic value = GetListValue(bindID, memberID, index);
            if (value is string)
            {
                return value;
            }
            else
            {
                if (value != null)
                {
                    return value.ToString();
                }
                else
                {
                    return string.Empty;
                }
            }
        }

        internal string GetText(string bindID, string memberID = "", bool isCustom = false)
        {
            dynamic value = GetValue(bindID, memberID, isCustom);
            if (value is string)
            {
                return value;
            }
            return string.Empty;
        }

        internal Image GetImage(string bindID, string memberID = "", bool isCustom = false)
        {
            dynamic value = GetValue(bindID, memberID, isCustom);
            if (value is Image)
            {
                return value;
            }
            return null;
        }

        internal Image GetTableImage(string bindID, string memberID = "", int index = 0, bool isCustom = false)
        {
            dynamic value = GetListValue(bindID, memberID, index);
            if (value is Image)
            {
                return value;
            }
            return null;
        }

        private dynamic GetValue(string bindID, string memberID, bool isCustom = false)
        {
            if (isCustom)
            {
                return GetDataWithCustom(bindID, memberID);
            }
            if (!string.IsNullOrWhiteSpace(bindID))
            {
                if (ContainsKey(bindID) && this[bindID] != null)
                {
                    object data = this[bindID];
                    if (!string.IsNullOrWhiteSpace(memberID))
                    {
                        return GetDataFromModel(data, memberID);
                    }
                    return data;
                }
            }
            return null;
        }

        internal dynamic GetListValue(string bindID, string memberID, int index = 0, bool isCustom = false)
        {
            if (isCustom)
            {
                return GetDataWithCustom(bindID, memberID, index);
            }
            if (!string.IsNullOrWhiteSpace(bindID))
            {
                if (ContainsKey(bindID) && this[bindID] != null && this[bindID] is IList)
                {
                    IList lst = this[bindID] as IList;
                    if (index >= 0 && index < lst.Count && lst[index] != null)
                    {
                        object data = lst[index];
                        if (!string.IsNullOrWhiteSpace(memberID))
                        {
                            return GetDataFromModel(data, memberID);
                        }
                        else
                        {
                            return data;
                        }
                    }
                }
            }
            return null;
        }

        private dynamic GetDataFromModel(object model, string memberID)
        {
            Type type = model.GetType();
            if (type.IsClass)
            {
                PropertyInfo propertyInfo = type.GetProperty(memberID);
                FieldInfo fieldInfo = type.GetField(memberID);
                dynamic value = null;
                if (propertyInfo != null)
                {
                    value = propertyInfo.GetValue(model, null);
                }
                else if (fieldInfo != null)
                {
                    value = fieldInfo.GetValue(model);
                }
                if (value != null)
                {
                    return value;
                }
            }
            return null;
        }

        private dynamic GetDataWithCustom(string bindID, string memberID, int index = 0)
        {
            if (ContainsKey(bindID) && this[bindID] != null
                && this[bindID] is ICustomDataBind && ContainsKey(bindID))
            {
                return (this[bindID] as ICustomDataBind).Bind(bindID, memberID, index, this[bindID]);
            }
            return null;
        }
    }
}